package com.detech.sboh.business.user.serviceimpl;

import cn.dev33.satoken.secure.BCrypt;
import com.detech.sboh.base.config.properties.HeadPictureProperties;
import com.detech.sboh.base.constant.Constants;
import com.detech.sboh.base.enumtype.MsgEnum;
import com.detech.sboh.base.exception.ServiceException;
import com.detech.sboh.base.hibernate.user.dao.TbUserDAO;
import com.detech.sboh.base.hibernate.user.entity.TbUser;
import com.detech.sboh.base.page.Page;
import com.detech.sboh.base.page.PageDAO;
import com.detech.sboh.base.satoken.enumtype.UserStatus;
import com.detech.sboh.base.satoken.properties.UserPasswordProperties;
import com.detech.sboh.base.util.UserFun;
import com.detech.sboh.business.login.service.LoginService;
import com.detech.sboh.business.user.model.UserOrderModel;
import com.detech.sboh.business.user.service.UserService;
import org.hibernate.query.NativeQuery;
import org.hibernate.query.internal.NativeQueryImpl;
import org.hibernate.transform.Transformers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Service
public class UserServiceImpl implements UserService {

    @Resource
    private PageDAO pageDAO;
    @Resource
    private TbUserDAO tbUserDAO;
    @Autowired
    private HeadPictureProperties headPictureProperties;
    @Autowired
    private UserPasswordProperties userPasswordProperties;
    @Resource
    private LoginService loginService;

    @Override
    public void register(String username, String realname, int age) {
        // 注册用户信息
        TbUser tbUser = new TbUser();
        tbUser.setUsername(username);
        tbUser.setRealname(realname);
        tbUser.setAge(age);
        tbUser.setPassword(BCrypt.hashpw(userPasswordProperties.getDefaultPwd()));
        tbUser.setDelFlag(UserStatus.OK.getCode());
        tbUser.setStatus(UserStatus.OK.getCode());
        List list = tbUserDAO.findByPropertyList("username",username);
        if (list!=null && list.size()>0) {
            throw new ServiceException("注册失败，用户帐号【"+username+"】已经存在");
        }
        tbUserDAO.save(tbUser);
        loginService.recordLogininfor(username, Constants.REGISTER, MsgEnum.OPRATE_SUCCESS.getMsg(),null);
    }

    @Override
    public boolean isUsernameExist(String username)  {
        TbUser tbUser = tbUserDAO.findByPropertyObject("username",username);
        if(tbUser!=null){
            return true;
        }
        return false;
    }

    @Override
    public TbUser findUserById(String id)  {
        return tbUserDAO.findById(id);
    }

    @Override
    public void updateUser(TbUser tbUser)  {
        tbUserDAO.update(tbUser);
    }

    @Override
    public void deleteUser(TbUser tbUser)  {
        tbUserDAO.delete(tbUser);
    }

    @Override
    public void uploadHeadPicture(String id,MultipartFile file) throws IOException {
        int index = file.getOriginalFilename().lastIndexOf(".");
        String newFileName = System.currentTimeMillis()+ UserFun.getRandomString(5)+file.getOriginalFilename().substring(index);//重新设置文件名
        String uploadFilePath = headPictureProperties.getFilePath();//得到上传文件主路径
        String filePath = uploadFilePath + newFileName;//得到文件的存储路径
        File newFile = new File(filePath);
        // 检测是否存在目录
        if (!newFile.getParentFile().exists()) {
            //不存在则创建目录
            newFile.getParentFile().mkdirs();
        }
        // 使用 spring 的 transferTo() 方法写入
        file.transferTo(newFile);

        TbUser tbUser = tbUserDAO.findById(id);
        tbUser.setHeadPicture(newFileName);
        tbUserDAO.update(tbUser);
    }

    @Override
    public Page loadUserList(Page page, String username, String realname)  {
        String hql = "from TbUser t where 1=1 ";
        if(username!=null && username.trim().length()>0){
            hql = hql + " and t.username like ? ";
            page.addParam("%"+username+"%");
        }
        if(realname!=null && realname.trim().length()>0){
            hql = hql + " and t.realname like ? ";
            page.addParam("%"+realname+"%");
        }
        hql = hql + " order by t.age desc ";
        page.setHql(hql);
        return pageDAO.queryDataList(page);
    }

    @Override
    public Page loadUserOrderListMap(Page page)  {
        String sql = "select u.username,count(o.ddbh) sl from tb_user u LEFT JOIN tb_order o on u.username=o.jlr GROUP BY u.username";
        page.setSql(sql);
        return pageDAO.sqlQueryDataList(page);
    }

    @Override
    public Page loadUserOrderList(Page page,String username,String realname)  {
        String sql = "select u.username,count(o.ddbh) sl from tb_user u LEFT JOIN tb_order o on u.username=o.jlr where 1=1 ";
        if(username!=null && username.trim().length()>0){
            sql = sql + " and u.username like ? ";
            page.addParam("%"+username+"%");
        }
        if(realname!=null && realname.trim().length()>0){
            sql = sql + " and u.realname like ? ";
            page.addParam("%"+realname+"%");
        }
        sql = sql + " GROUP BY u.username ";
        page.setSql(sql);
        page.addColumn("username",new org.hibernate.type.StringType());
        page.addColumn("sl",new org.hibernate.type.IntegerType());
        page.setReturnType(UserOrderModel.class);
        return pageDAO.sqlQueryDataList(page);
    }

    @Override
    public Page loadUserListMap(Page page, String username, String realname)  {
        String sql = "select * from Tb_User t where 1=1 ";
        if(username!=null && username.trim().length()>0){
            sql = sql + " and t.username like ? ";
            page.addParam("%"+username+"%");
        }
        if(realname!=null && realname.trim().length()>0){
            sql = sql + " and t.realname like ? ";
            page.addParam("%"+realname+"%");
        }
        sql = sql + " order by t.age desc ";
        page.setSql(sql);
        return pageDAO.sqlQueryDataList(page);
    }

    @Override
    public List<TbUser> loadUserListNoPage(String username, String realname)  {
        List paramList = new ArrayList();
        String hql = "from TbUser t where 1=1 ";
        if(username!=null && username.trim().length()>0){
            hql = hql + " and t.username like ? ";
            paramList.add("%"+username+"%");
        }
        if(realname!=null && realname.trim().length()>0){
            hql = hql + " and t.realname like ? ";
            paramList.add("%"+realname+"%");
        }
        hql = hql + " order by t.age desc ";
        return tbUserDAO.find(hql,paramList);
    }

    @Override
    public List loadUserListMapNoPage(String username, String realname)  {
        List paramList = new ArrayList();
        String sql = "select t.id,t.username,t.realname,t.age from Tb_User t where 1=1 ";
        if(username!=null && username.trim().length()>0){
            sql = sql + " and t.username like ? ";
            paramList.add("%"+username+"%");
        }
        if(realname!=null && realname.trim().length()>0){
            sql = sql + " and t.realname like ? ";
            paramList.add("%"+realname+"%");
        }
        sql = sql + " order by t.age desc ";
        NativeQuery nativeQuery = tbUserDAO.getCurrentSession().createSQLQuery(sql);
        nativeQuery.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        if(paramList!=null && paramList.size()>0){
            for(int i=1;i<=paramList.size();i++){
                nativeQuery.setParameter(i, paramList.get(i-1));
            }
        }
        return nativeQuery.list();
    }

    @Override
    public List loadUserListSqlNoPageNoParam()  {
        String sql = "select * from tb_user t ";
        NativeQuery nativeQuery = tbUserDAO.getCurrentSession().createNativeQuery(sql);
        nativeQuery.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        return nativeQuery.list();
    }

    @Override
    public List loadUserListSqlNoPageParam(String username)  {
        String sql = "select * from tb_user t where t.username=? ";
        NativeQuery nativeQuery = tbUserDAO.getCurrentSession().createNativeQuery(sql);
        nativeQuery.setParameter(1,username);
        nativeQuery.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        return nativeQuery.list();
    }

    @Override
    public void deleteUserById(String userId) {
        TbUser tbUser = tbUserDAO.findById(userId);
        if(tbUser!=null){
            tbUserDAO.delete(tbUser);
        }
    }
}
